package br.edu.ufcg.unknown.semantico;

import br.edu.ufcg.unknown.lexico.Token;
import br.edu.ufcg.unknown.sintatico.IdentificaTK;

public class AnalisadorSemantico {

	private TabelaDeSimbolos simbolos;

	private Atributo ultimoAtributo;

	private Tipo ultimoTipo;

	private static final IdentificaTK ident = new IdentificaTK();

	public AnalisadorSemantico() {
		this.simbolos = new TabelaDeSimbolos();
		this.ultimoAtributo = null;
		this.ultimoTipo = null;
	}

	public void addSimbolo(Token tk, Tipo tipo) {
		this.simbolos.addSimbolo(tk, tipo);
	}

	public void setAtributo(Token tk) {

		this.ultimoAtributo = this.simbolos.getAtributo(tk);

		if (this.ultimoAtributo == null) {
			this.ultimoAtributo = new Atributo(tk.getLexema(), new Tipo(tk));
		}
	}

	public void setTipo(Token tk) {

		Tipo t = this.simbolos.getTipo(tk);
		if (this.ident.eh_IDENTIFICADOR(tk)) {
			if (t == null) {
				// TODO lanca erro
				return;
			}
		} else {
			t = new Tipo(tk);
		}

		if (this.ultimoTipo == null) {
			this.ultimoTipo = t;
		} else if (!this.ultimoTipo.equals(t)) {
			// TODO lança erro!!!
			return;
		}

	}

	public void verificaCompatibilidade() {

		if (this.ultimoTipo == null || this.ultimoAtributo == null) {
			// TODO lancar erro
			return;
		}

		if (!this.ultimoTipo.equals(this.ultimoAtributo.getTipo())) {
			// TODO lancar erro
			return;
		}

	}

	public boolean existeAtributo(Token identificador) {
		return this.simbolos.getAtributo(identificador) != null;
	}

	public void verificaOperadorSoma() {
		if (this.ultimoTipo == null || this.ultimoAtributo == null) {
			// TODO lancar erro
			return;
		}

		if (this.ultimoTipo.ehInteger() || this.ultimoTipo.ehCadeia()) {

		} else {
			// TODO lancar erro
			return;
		}
	}
	
	public void verificaEhInteger() {
		if (this.ultimoTipo == null || this.ultimoAtributo == null) {
			// TODO lancar erro
			return;
		}

		if (this.ultimoTipo.ehInteger()) {

		} else {
			// TODO lancar erro
			return;
		}
	}
	public void verificaEhBoolean() {
		if (this.ultimoTipo == null || this.ultimoAtributo == null) {
			// TODO lancar erro
			return;
		}

		if (this.ultimoTipo.ehBoolean()) {

		} else {
			// TODO lancar erro
			return;
		}
		
	}
	public void verificaEhRelacionalFim() {
		verificaEhInteger();
		this.ultimoTipo = new Tipo(new Token("BOOLEAN", "t_ident", "t_boolean", true));
	}
	
}
